﻿using System;
using System.Collections.Generic;

namespace Luna.Data.Budget
{
    public class BudgetProvider : LunaDataProvider, IBudgetProvider
    {
        #region Mappers

        public BudgetDataMapper BudgetMapper { get; set; }

        public CategoryDataMapper CategoryMapper { get; set; }

        public LineDataMapper LineMapper { get; set; }

        #endregion Mappers

        #region Budget

        public void BudgetDelete(Guid budgetID)
        {
            WrapperTransactional(T => BudgetMapper.Delete(T, budgetID));
        }

        public IBudgetData BudgetGet(Guid budgetID)
        {
            return WrapperTransactional(T => BudgetMapper.Get(T, budgetID));
        }

        public IEnumerable<IBudgetData> BudgetGetAll()
        {
            return WrapperTransactional(T => BudgetMapper.GetAll(T));
        }

        public IEnumerable<IBudgetData> BudgetGetAllByMainBudget(Guid mainBudgetID)
        {
            return WrapperTransactional(T => BudgetMapper.GetAllByMainBudgetID(T, mainBudgetID));
        }

        public void BudgetSave(IBudgetData budget)
        {
            BudgetSave(null);
        }

        public void BudgetSave(IBudgetData budget, IEnumerable<ILineData> lines)
        {
            WrapperTransactional(T =>
            {
                BudgetMapper.Save(T, budget);

                var oldLines = LineMapper.GetAllByBudgetID(T, budget.PK);

                HashSet<Guid> newLinesIDs = new HashSet<Guid>();
                if (lines != null)
                {
                    foreach (var newLine in lines)
                    {
                        LineMapper.Save(T, newLine);
                        newLinesIDs.Add(newLine.PK);
                    }
                }

                foreach (var oldLine in oldLines)
                {
                    if (!newLinesIDs.Contains(oldLine.PK))
                    {
                        LineMapper.Delete(T, oldLine.PK);
                    }
                }
            });
        }

        #endregion Budget

        #region Categories

        public void CategoryDelete(Guid categoryID)
        {
            WrapperTransactional(T => CategoryMapper.Delete(T, categoryID));
        }

        public ICategoryData CategoryGet(Guid categoryID)
        {
            return WrapperTransactional(T => CategoryMapper.Get(T, categoryID));
        }

        public IEnumerable<ICategoryData> CategoryGetAll()
        {
            return WrapperTransactional(T => CategoryMapper.GetAll(T));
        }

        public void CategorySave(ICategoryData category)
        {
            WrapperTransactional(T =>
            {
                CategoryMapper.Save(T, category);
            });
        }

        #endregion Categories

        #region Lines

        public void LineDelete(Guid lineID)
        {
            WrapperTransactional(T => LineMapper.Delete(T, lineID));
        }

        public ILineData LineGet(Guid lineID)
        {
            return WrapperTransactional(T => LineMapper.Get(T, lineID));
        }

        public IEnumerable<ILineData> LineGetAll()
        {
            return WrapperTransactional(T => LineMapper.GetAll(T));
        }

        public IEnumerable<ILineData> LineGetAllByBudget(Guid budgetID)
        {
            return WrapperTransactional(T => LineMapper.GetAllByBudgetID(T, budgetID));
        }

        public void LineSave(ILineData line)
        {
            WrapperTransactional(T =>
            {
                LineMapper.Save(T, line);
            });
        }

        #endregion Lines
    }
}